#include <alloca.h>
//
// Created by xsh on 2025/5/31.
//

#include "instrument.h"
#include <math.h>
#include <cstring>
#include <map>
#include <jni.h>
#include <android/log.h>
#include "SawSynth.h"
#include "MidiTool.cpp"
// 创建乐器实例
SawSynth* createInstrument()
{
    return new SawSynth();
}
// 销毁乐器实例
void destroyInstrument(Instrument *inst)
{
    delete static_cast<SawSynth *>(inst); // 转换为实际类型后删除
}
double SawSynth::genWave(short* buffer, int numSamples, double phase, double sampleRate)
{
    // Convert detune from cents to frequency multiplier: 1 cent = 1/100 of a semitone
    double detuneFactor = pow(2.0, detune / 1200.0); // 1200 cents = 1 octave
    const double tunedFrequency = frequency * detuneFactor;
    const double phaseIncrement = 2.0 * M_PI * tunedFrequency / sampleRate;
    //const double phaseIncrement = 2.0 * M_PI * frequency / sampleRate;

    for (int i = 0; i < numSamples; ++i) {
        // 锯齿波公式：(phase / (2π)) * 2 - 1 → [-1, 1]
        double sample = (phase / (2 * M_PI)) * 2.0 - 1.0;
        buffer[i] = static_cast<short>(sample * amp * 32767.0); // 转换为 PCM 16-bit
        phase += phaseIncrement;

        // 保持相位在 [0, 2π) 区间内
        if (phase >= 2.0 * M_PI) {
            phase -= 2.0 * M_PI;
        }
    }

    return phase; // 返回更新后的相位
}
// 2025/6/4 修改 先写JNIEnv 以后再模块化优化代码 先实现功能
// 统一在这个转换int或者double类型
void SawSynth::onEvent(const char* eventName, jint value)
{
   if(strcmp(eventName,"noteOn")==0)
    {
        this->frequency = midiNoteToFrequency(value);
    }
}
void SawSynth::onEvent(const char *eventName, jdouble value)
{
    if (strcmp(eventName, "setAmplitude") == 0)
    {
        this->amp = value;
        __android_log_print(ANDROID_LOG_DEBUG, "SawSynth", "%f",value);
    }
    else if(strcmp(eventName,"setDetune") ==0)
    {
        // value comes from SeekBar: 0 ~ 100
        double semitoneValue = (value / 100.0) * 48.0; // scale to 0 ~ 48 semitones
        double centValue = semitoneValue * 100.0;
        this->detune = centValue;
        __android_log_print(ANDROID_LOG_DEBUG, "SawSynth", "%f",centValue);
    }
}
double SawSynth::processFilter(double sample,double &prevSample1,double &prevSample2)
{

}
